package com.chuangjiangx.member.manager.web.web.basic.controller;

import com.chuangjiangx.commons.CJBeanUtils;
import com.chuangjiangx.commons.DateUtils;
import com.chuangjiangx.commons.PageUtils;
import com.chuangjiangx.commons.page.PagingResult;
import com.chuangjiangx.commons.request.Page;
import com.chuangjiangx.commons.response.Response;
import com.chuangjiangx.commons.response.ResponseUtils;
import com.chuangjiangx.member.basic.ddd.query.MemberCountQuery;
import com.chuangjiangx.member.basic.ddd.query.condition.MemberVolumeCondition;
import com.chuangjiangx.member.basic.ddd.query.condition.MemberVolumeDetailCondition;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberVolumeAndTotalDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.MemberVolumeDetailDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.TerminalMemberVolumeAndTotalDTO;
import com.chuangjiangx.member.basic.ddd.query.dto.TerminalMemberVolumeDTO;
import com.chuangjiangx.member.manager.basic.web.controller.BaseController;
import com.chuangjiangx.member.manager.basic.web.interceptor.Login;
import com.chuangjiangx.member.manager.basic.web.interceptor.Permissions;
import com.chuangjiangx.member.manager.common.Constants;
import com.chuangjiangx.member.manager.common.RequestHeadersUtil;
import com.chuangjiangx.member.manager.common.ThreadLocalUser;
import com.chuangjiangx.member.manager.web.web.basic.request.*;
import com.chuangjiangx.member.manager.web.web.basic.response.*;
import com.chuangjiangx.member.manager.web.web.stored.response.StoreMemberVolumeAndTotalResponse;
import com.chuangjiangx.member.manager.web.web.stored.response.StoreMemberVolumeResponse;
import com.chuangjiangx.member.stored.ddd.query.dto.StoreMemberVolumeAndTotalDTO;
import com.chuangjiangx.member.stored.ddd.query.dto.StoreMemberVolumeDTO;
import com.sun.jmx.snmp.ThreadContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * 会员量统计
 *
 * @author 李孝延
 */
@RestController
@RequestMapping(value = "/api/mbr/member-count", produces = "application/json")
public class MemberCountController extends BaseController {

    private final MemberCountQuery memberCountQuery;

    @Autowired
    public MemberCountController(MemberCountQuery memberCountQuery) {
        this.memberCountQuery = memberCountQuery;
    }


    /**
     * 按照时间统计注册会员量--商户权限
     *
     * @see MemberVolumeAndTotalResponse
     */
    @RequestMapping(value = "/count-by-register-time-all")
    @Login
    @Permissions("50010")
    public Response countByRegisterTimeForMerchant(
                                                   @Validated @RequestBody CountByRegisterTimeRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(user.getMerchantId());
        condition.setRegisterStoreId(user.getStoreId());

        MemberVolumeAndTotalDTO memberVolumeAndTotalDTO = memberCountQuery.getDayOrHourCountListForMerchant(condition);

        MemberVolumeAndTotalResponse response = new MemberVolumeAndTotalResponse();
        BeanUtils.copyProperties(memberVolumeAndTotalDTO, response);

        return ResponseUtils.success(response);
    }

    /**
     * 按照时间统计注册会员量--门店权限
     *
     * @see MemberVolumeAndTotalResponse
     */
    @RequestMapping(value = "/count-by-register-time-its")
    @Login
    @Permissions("51010")
    public Response countByRegisterTimeForStore(
                                                @Validated @RequestBody CountByRegisterTimeRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime() == null ? null : DateUtils.addDate(param.getEndTime()));

        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(user.getMerchantId());
        condition.setRegisterStoreId(user.getStoreId());
        PageUtils.copyPage(condition, param.getPage());
        MemberVolumeAndTotalDTO memberVolumeAndTotalDTO = memberCountQuery.getDayOrHourCountListForForStore(condition);

        MemberVolumeAndTotalResponse response = new MemberVolumeAndTotalResponse();
        BeanUtils.copyProperties(memberVolumeAndTotalDTO, response);
        return ResponseUtils.success(response);
    }

    /**
     * 按照时间统计注册会员量明细--商户权限
     *
     * @map dataList
     * @see MemberDetailResponse
     */
    @RequestMapping(value = "/count-by-register-time-detail-all")
    @Login
    @Permissions("50011")
    public Response countByRegisterTimeDetailForMerchant(
                                                         @Validated @RequestBody CountByRegisterTimeRequest param) {
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        MemberVolumeDetailCondition condition = memberVolumeDetailInfoConvert(param);
        PagingResult<MemberVolumeDetailDTO> countByRegisterTimeDetailList =
                memberCountQuery.getMemberVolumeDetailForMerchant(condition);
        List<MemberDetailResponse> memberDetailRespons = CJBeanUtils.convertCollection(
                countByRegisterTimeDetailList.getItems(), MemberDetailResponse.class, (source, target) -> {
                    if (source.getStoreUser().equals("-")) {
                        target.setStoreUser(user.getMerchantName());
                    }
                });

        return ResponseUtils.successPage(param.getPage(), countByRegisterTimeDetailList,
                "dataList", memberDetailRespons);
    }

    /**
     * 按照时间统计注册会员量明细--商户权限 导出
     */
    @RequestMapping(value = "/export/count-by-register-time-detail-all")
    @Login
    //@Permissions("50011")
    public void exportCountByRegisterTimeDetailForMerchant(HttpSession session,
                                                           HttpServletResponse response,
                                                           HttpServletRequest request) throws IOException, ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String pageNo = request.getParameter("pageNO");
        CountByRegisterTimeRequest param = new CountByRegisterTimeRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照时间统计注册会员量明细");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<MemberDetailResponse> list = getCountByRegisterTimeDetailForMerchant(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            getExportCountByRegisterTimeDetailData(sdf, bw, list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }

    }

    private void getExportCountByRegisterTimeDetailData(SimpleDateFormat sdf, BufferedWriter bw, List<MemberDetailResponse> list) throws IOException {
        bw.append("序号").append(",")
                .append("注册时间").append(",")
                .append("会员卡号").append(",")
                .append("会员名称").append(",")
                .append("手机号").append(",")
                .append("操作人").append(",")
                .append("来源").append(",").append("\r");

        if (list != null && !list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) {
                MemberDetailResponse data = list.get(i);
                String registerTime = null;
                if (data.getRegisterTime() != null) {
                    registerTime = sdf.format(data.getRegisterTime());
                }
                bw.append(String.valueOf(i + 1)).append(",")
                        .append(registerTime == null ? "" : registerTime).append(",")
                        .append(data.getMemberCardNum() == null ? "" : data.getMemberCardNum()).append(",")
                        .append(data.getName() == null ? "" : data.getName()).append(",")
                        .append(data.getMobile() == null ? "" : data.getMobile()).append(",")
                        .append(data.getStoreUser() == null ? "" : data.getStoreUser()).append(",")
                        .append(data.getTerminalTypeText() == null ? "" : data.getTerminalTypeText()).append(",")
                        .append("\r");
            }
        }
    }

    private List<MemberDetailResponse> getCountByRegisterTimeDetailForMerchant(HttpSession session, @Validated @RequestBody CountByRegisterTimeRequest param) {
        MemberVolumeDetailCondition condition = memberVolumeDetailInfoConvert(param);
        PagingResult<MemberVolumeDetailDTO> countByRegisterTimeDetailList =
                memberCountQuery.getMemberVolumeDetailForMerchant(condition);
        return CJBeanUtils.convertCollection(
                countByRegisterTimeDetailList.getItems(), MemberDetailResponse.class);
    }

    /**
     * 按照时间统计注册会员量明细--门店权限
     *
     * @map dataList
     * @see MemberDetailResponse
     */
    @RequestMapping(value = "/count-by-register-time-detail-its")
    @Login
    @Permissions("51011")
    public Response countByRegisterTimeDetailForStore(
                                                      @Validated @RequestBody CountByRegisterTimeRequest param) {
        MemberVolumeDetailCondition condition = memberVolumeDetailInfoConvert(param);
        ThreadLocalUser user = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);

        PagingResult<MemberVolumeDetailDTO> countByRegisterTimeDetailList =
                memberCountQuery.getMemberVolumeDetailForStore(condition);
        List<MemberDetailResponse> memberDetailRespons = CJBeanUtils.convertCollection(
                countByRegisterTimeDetailList.getItems(), MemberDetailResponse.class, (source, target) -> {
                    if (source.getStoreUser().equals("-")) {
                        target.setStoreUser(user.getMerchantName());
                    }
                });

        return ResponseUtils.successPage(param.getPage(), countByRegisterTimeDetailList,
                "dataList", memberDetailRespons);
    }


    /**
     * 按照时间统计注册会员量明细--门店权限 导出
     */
    @RequestMapping(value = "/export/count-by-register-time-detail-its")
    @Login
    //@Permissions("50011")
    public void exportCountByRegisterTimeDetailForStore(HttpSession session,
                                                        HttpServletResponse response,
                                                        HttpServletRequest request) throws ParseException, IOException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String pageNo = request.getParameter("pageNO");
        CountByRegisterTimeRequest param = new CountByRegisterTimeRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照时间统计注册会员量明细");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<MemberDetailResponse> list = getCountByRegisterTimeDetailForStore(param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            getExportCountByRegisterTimeDetailData(sdf, bw, list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }


    }

    private List<MemberDetailResponse> getCountByRegisterTimeDetailForStore(@Validated @RequestBody CountByRegisterTimeRequest param) {
        MemberVolumeDetailCondition condition = memberVolumeDetailInfoConvert(param);
        PagingResult<MemberVolumeDetailDTO> countByRegisterTimeDetailList =
                memberCountQuery.getMemberVolumeDetailForStore(condition);
        return CJBeanUtils.convertCollection(
                countByRegisterTimeDetailList.getItems(), MemberDetailResponse.class);
    }

    private MemberVolumeDetailCondition memberVolumeDetailInfoConvert(
                                                                      CountByRegisterTimeRequest param) {
        MemberVolumeDetailCondition condition = new MemberVolumeDetailCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());
        condition.setNameOrMobile(param.getNameOrMobile());
        condition.setTerminalType(param.getTerminalType());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setRegisterStoreId(userCommon.getStoreId());
        condition.setMerchantId(userCommon.getMerchantId());
        PageUtils.copyPage(condition, param.getPage());
        return condition;
    }

    /**
     * 按照门店统计前10注册会员量图表--商户
     *
     * @see StoreMemberVolumeAndTotalResponse
     */
    @RequestMapping(value = "/count-Top10-by-store-chart-all")
    @Login
    @Permissions("50016")
    public Response countTop10ChartByStore(HttpSession session,
                                           @Validated @RequestBody CountByStoreRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());

        PageUtils.copyPage(condition, param.getPage());
        StoreMemberVolumeAndTotalDTO storeMemberVolumeAndTotalDTO =
                memberCountQuery.getStoreCountTop10Chart(condition);
        StoreMemberVolumeAndTotalResponse response = new StoreMemberVolumeAndTotalResponse();

        BeanUtils.copyProperties(storeMemberVolumeAndTotalDTO, response);
        return ResponseUtils.success(response);
    }

    /**
     * 按照门店统计注册会员量列表--商户
     *
     * @map dataList
     * @see StoreMemberVolumeResponse
     */
    @RequestMapping(value = "/count-by-store-list-all")
    @Login
    @Permissions("50014")
    public Response countListByStore(HttpSession session,
                                     @Validated @RequestBody CountByStoreRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<StoreMemberVolumeDTO> storeList =
                memberCountQuery.getStoreCountList(condition);
        List<StoreMemberVolumeResponse> response = CJBeanUtils.convertCollection(
                storeList.getItems(), StoreMemberVolumeResponse.class);
        return ResponseUtils.successPage(param.getPage(), storeList, "dataList", response);
    }


    /**
     * 按照门店统计注册会员量列表--商户 导出
     *
     * @map dataList
     * @see StoreMemberVolumeResponse
     */
    @RequestMapping(value = "/export/count-by-store-list-all")
    @Login
    public void exportCountListByStore(HttpSession session,
                                       HttpServletResponse response,
                                       HttpServletRequest request) throws IOException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String pageNo = request.getParameter("pageNO");
        CountByStoreRequest param = new CountByStoreRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);

        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照门店统计注册会员量列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<StoreMemberVolumeResponse> list = getExportCountListByStore(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("开通门店").append(",")
                    .append("会员量").append(",")
                    .append("\r");
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    StoreMemberVolumeResponse data = list.get(i);
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(data.getStoreName() == null ? "" : data.getStoreName()).append(",")
                            .append(String.valueOf(data.getCount())).append(",")
                            .append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }
    }

    private List<StoreMemberVolumeResponse> getExportCountListByStore(HttpSession session, @Validated @RequestBody CountByStoreRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<StoreMemberVolumeDTO> storeList =
                memberCountQuery.getStoreCountList(condition);
        return CJBeanUtils.convertCollection(
                storeList.getItems(), StoreMemberVolumeResponse.class);
    }


    /**
     * 按照门店统计注册会员量明细--商户
     *
     * @map dataList
     * @see CountByStoreDetailResponse
     */
    @RequestMapping(value = "/count-by-store-detail-all")
    @Login
    @Permissions("50015")
    public Response countListByStoreDetail(HttpSession session,
                                           @Validated @RequestBody CountByStoreDetailRequest param) {
        MemberVolumeDetailCondition condition = new MemberVolumeDetailCondition();

        condition.setMerchantUserId(param.getMerchantUserId());
        condition.setRegisterStoreId(param.getRegisterStoreId());
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());
        condition.setTerminalType(param.getTerminalType());
        condition.setSex(param.getSex());
        condition.setNameOrMobile(param.getNameOrMobile());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());

        PageUtils.copyPage(condition, param.getPage());
        PagingResult<MemberVolumeDetailDTO> storeList = memberCountQuery.getMemberVolumeDetailForMerchant(condition);
        List<CountByStoreDetailResponse> countByStoreDetailRespons = CJBeanUtils.convertCollection(
                storeList.getItems(), CountByStoreDetailResponse.class, (source, target) -> {
                    if (source.getStoreUser().equals("-")) {
                        target.setStoreUser(userCommon.getMerchantName());
                    }
                });
        return ResponseUtils.successPage(param.getPage(), storeList,
                "dataList", countByStoreDetailRespons);
    }


    /**
     * 按照门店统计注册会员量明细--商户 导出
     */
    @RequestMapping(value = "/export/count-by-store-detail-all")
    @Login
    //@Permissions("50011")
    public void exportCountListByStoreDetail(HttpSession session,
                                             HttpServletResponse response,
                                             HttpServletRequest request) throws IOException, ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String registerStoreId = request.getParameter("registerStoreId");
        String merchantUserId = request.getParameter("merchantUserId");
        String sex = request.getParameter("sex");
        String terminalType = request.getParameter("terminalType");
        String nameOrMobile = request.getParameter("nameOrMobile");
        String pageNo = request.getParameter("pageNO");
        CountByStoreDetailRequest param = new CountByStoreDetailRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }
        if (!"".equals(registerStoreId)) {
            param.setRegisterStoreId(Long.parseLong(registerStoreId));
        }
        if (!"".equals(merchantUserId)) {
            param.setMerchantUserId(Long.parseLong(merchantUserId));
        }
        if (!"".equals(sex)) {
            param.setSex(Byte.valueOf(sex));
        }
        if (!"".equals(terminalType)) {
            param.setTerminalType(Byte.valueOf(terminalType));
        }
        if (!"".equals(nameOrMobile)) {
            param.setNameOrMobile(nameOrMobile);
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);


        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照门店统计注册会员量明细");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<CountByStoreDetailResponse> list = getExportCountListByStoreDetail(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("注册时间").append(",")
                    .append("会员卡号").append(",")
                    .append("会员名称").append(",")
                    .append("手机号").append(",")
                    .append("操作人").append(",")
                    .append("来源").append(",").append("\r");
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    CountByStoreDetailResponse data = list.get(i);
                    String registerTime = null;
                    if (data.getRegisterTime() != null) {
                        registerTime = sdf.format(data.getRegisterTime());
                    }
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(registerTime == null ? "" : registerTime).append(",")
                            .append(data.getMemberCardNum() == null ? "" : data.getMemberCardNum()).append(",")
                            .append(data.getName() == null ? "" : data.getName()).append(",")
                            .append(data.getMobile() == null ? "" : data.getMobile()).append(",")
                            .append(data.getStoreUser() == null ? "" : data.getStoreUser()).append(",")
                            .append(data.getTerminalTypeText() == null ? "" : data.getTerminalTypeText()).append(",")
                            .append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }

    }

    private List<CountByStoreDetailResponse> getExportCountListByStoreDetail(HttpSession session, @Validated @RequestBody CountByStoreDetailRequest param) {
        MemberVolumeDetailCondition condition = new MemberVolumeDetailCondition();

        condition.setMerchantUserId(param.getMerchantUserId());
        condition.setRegisterStoreId(param.getRegisterStoreId());
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());
        condition.setTerminalType(param.getTerminalType());
        condition.setSex(param.getSex());
        condition.setNameOrMobile(param.getNameOrMobile());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());

        PageUtils.copyPage(condition, param.getPage());
        PagingResult<MemberVolumeDetailDTO> storeList = memberCountQuery.getMemberVolumeDetailForMerchant(condition);
        return CJBeanUtils.convertCollection(
                storeList.getItems(), CountByStoreDetailResponse.class);
    }

    /**
     * 按照终端类型统计注册会员量图表--商户权限
     *
     * @see TerminalMemberVolumeAndTotalResponse
     */
    @RequestMapping(value = "/count-by-terminal-chart-all")
    @Login
    @Permissions("50012")
    public Response countChartByTerminalForMerchant(HttpSession session,
                                                    @Validated @RequestBody CountByTerminalRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        TerminalMemberVolumeAndTotalDTO terminalMemberVolumeAndTotalDTO =
                memberCountQuery.getTerminalCountChartForMerchant(condition);
        TerminalMemberVolumeAndTotalResponse response = new TerminalMemberVolumeAndTotalResponse();
        BeanUtils.copyProperties(terminalMemberVolumeAndTotalDTO, response);

        return ResponseUtils.success(response);
    }

    /**
     * 按照终端类型统计注册会员量图表--门店权限
     *
     * @see TerminalMemberVolumeAndTotalResponse
     */
    @RequestMapping(value = "/count-by-terminal-chart-its")
    @Login
    @Permissions("51012")
    public Response countChartByTerminalForStore(HttpSession session, @Validated @RequestBody CountByTerminalRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        TerminalMemberVolumeAndTotalDTO terminalMemberVolumeAndTotalDTO = memberCountQuery.getTerminalCountChartForStore(condition);
        TerminalMemberVolumeAndTotalResponse response = new TerminalMemberVolumeAndTotalResponse();
        BeanUtils.copyProperties(terminalMemberVolumeAndTotalDTO, response);
        return ResponseUtils.success(response);
    }

    /**
     * 按照终端类型统计注册会员量列表--商户权限
     *
     * @map dataList
     * @see TerminalMemberVolumeForMerchantResponse
     */
    @RequestMapping(value = "/count-by-terminal-list-all")
    @Login
    @Permissions("50017")
    public Response countListByTerminalForMerchant(HttpSession session, @Validated @RequestBody CountListByTerminalRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<TerminalMemberVolumeDTO> list = memberCountQuery.getTerminalCountListForMerchant(condition);
        List<TerminalMemberVolumeForMerchantResponse> response = CJBeanUtils.convertCollection(list.getItems(), TerminalMemberVolumeForMerchantResponse.class);
        return ResponseUtils.successPage(param.getPage(), list, "dataList", response);
    }


    /**
     * 按照终端类型统计注册会员量列表--商户权限 导出
     */
    @RequestMapping(value = "/export/count-by-terminal-list-all")
    @Login
    //@Permissions("50011")
    public void exportCountListByTerminalForMerchant(HttpSession session,
                                                     HttpServletResponse response,
                                                     HttpServletRequest request) throws IOException, ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String pageNo = request.getParameter("pageNO");
        CountListByTerminalRequest param = new CountListByTerminalRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);


        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照终端类型统计注册会员量列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<TerminalMemberVolumeForMerchantResponse> list = getExportCountListByTerminalForMerchant(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("来源").append(",")
                    .append("会员量").append(",")
                    .append("\r");
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    TerminalMemberVolumeForMerchantResponse data = list.get(i);
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(data.getTerminalTypeText() == null ? "" : data.getTerminalTypeText()).append(",")
                            .append(String.valueOf(data.getCount())).append(",")
                            .append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }
    }

    private List<TerminalMemberVolumeForMerchantResponse> getExportCountListByTerminalForMerchant(HttpSession session, @Validated @RequestBody CountListByTerminalRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<TerminalMemberVolumeDTO> list = memberCountQuery.getTerminalCountListForMerchant(condition);
        return CJBeanUtils.convertCollection(list.getItems(), TerminalMemberVolumeForMerchantResponse.class);
    }

    /**
     * 按照终端类型统计注册会员量列表--门店权限
     *
     * @map dataList
     * @see TerminalMemberVolumeForStoreResponse
     */
    @RequestMapping(value = "/count-by-terminal-list-its")
    @Login
    @Permissions("51017")
    public Response countListByTerminalForStore(HttpSession session, @Validated @RequestBody CountListByTerminalRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<TerminalMemberVolumeDTO> list = memberCountQuery.getTerminalCountListForStore(condition);
        List<TerminalMemberVolumeForStoreResponse> response = CJBeanUtils.convertCollection(list.getItems(), TerminalMemberVolumeForStoreResponse.class);
        return ResponseUtils.successPage(param.getPage(), list, "dataList", response);
    }


    /**
     * 按照终端类型统计注册会员量列表--门店权限 导出
     */
    @RequestMapping(value = "/export/count-by-terminal-list-its")
    @Login
    //@Permissions("50011")
    public void exportCountListByTerminalForStore(HttpSession session,
                                                  HttpServletResponse response,
                                                  HttpServletRequest request) throws ParseException, IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String pageNo = request.getParameter("pageNO");
        CountListByTerminalRequest param = new CountListByTerminalRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);


        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照终端类型统计注册会员量列表");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<TerminalMemberVolumeForStoreResponse> list = getExportCountListByTerminalForStore(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            bw.append("序号").append(",")
                    .append("来源").append(",")
                    .append("会员量").append(",")
                    .append("\r");
            if (list != null && !list.isEmpty()) {
                for (int i = 0; i < list.size(); i++) {
                    TerminalMemberVolumeForStoreResponse data = list.get(i);
                    bw.append(String.valueOf(i + 1)).append(",")
                            .append(data.getTerminalTypeText()).append(",")
                            .append(String.valueOf(data.getCount())).append(",")
                            .append("\r");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }


    }

    private List<TerminalMemberVolumeForStoreResponse> getExportCountListByTerminalForStore(HttpSession session, @Validated @RequestBody CountListByTerminalRequest param) {
        MemberVolumeCondition condition = new MemberVolumeCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());

        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());
        PageUtils.copyPage(condition, param.getPage());

        PagingResult<TerminalMemberVolumeDTO> list = memberCountQuery.getTerminalCountListForStore(condition);
        return CJBeanUtils.convertCollection(list.getItems(), TerminalMemberVolumeForStoreResponse.class);
    }


    /**
     * 按照终端类型统计注册会员量明细--商户权限
     *
     * @map dataList
     * @see CountByTerminalDetailResponse
     */
    @RequestMapping(value = "/count-by-terminal-detail-all")
    @Login
    @Permissions("50013")
    public Response countByTerminalDetailForMerchant(HttpSession session,
                                                     @Validated @RequestBody CountByTerminalDetailRequest param) {
        MemberVolumeDetailCondition condition = countByTerminalInfoConvert(param);
        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());

        PagingResult<MemberVolumeDetailDTO> storeList = memberCountQuery.getMemberVolumeDetailForMerchant(condition);
        List<CountByTerminalDetailResponse> countByTerminalDetailResponse =
                CJBeanUtils.convertCollection(storeList.getItems(), CountByTerminalDetailResponse.class, (source, target) -> {
                    if (source.getStoreUser().equals("-")) {
                        target.setStoreUser(userCommon.getMerchantName());
                    }
                });

        return ResponseUtils.successPage(param.getPage(), storeList,
                "dataList", countByTerminalDetailResponse);
    }

    /**
     * 按照终端类型统计注册会员量明细--商户权限 导出
     */
    @RequestMapping(value = "/export/count-by-terminal-detail-all")
    @Login
    public void exportCountByTerminalDetailForMerchant(HttpSession session,
                                                       HttpServletResponse response,
                                                       HttpServletRequest request) throws IOException, ParseException {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String registerTerminalType = request.getParameter("registerTerminalType");
        String nameOrMobile = request.getParameter("nameOrMobile");
        String pageNo = request.getParameter("pageNO");
        CountByTerminalDetailRequest param = new CountByTerminalDetailRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }
        if (!"".equals(registerTerminalType)) {
            param.setTerminalType(Byte.valueOf(registerTerminalType));
        }
        if (!"".equals(nameOrMobile)) {
            param.setNameOrMobile(nameOrMobile);
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);


        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照终端类型统计注册会员量明细");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<CountByTerminalDetailResponse> list = getExportCountByTerminalDetailForMerchant(session, param);
            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            getExportCountByTerminalDetail(sdf, bw, list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }

    }

    private List<CountByTerminalDetailResponse> getExportCountByTerminalDetailForMerchant(HttpSession session, @Validated @RequestBody CountByTerminalDetailRequest param) {
        MemberVolumeDetailCondition condition = countByTerminalInfoConvert(param);
        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());

        PagingResult<MemberVolumeDetailDTO> storeList = memberCountQuery.getMemberVolumeDetailForMerchant(condition);
        return CJBeanUtils.convertCollection(storeList.getItems(), CountByTerminalDetailResponse.class);
    }

    /**
     * 按照终端类型统计注册会员量明细--门店权限
     *
     * @map dataList
     * @see CountByTerminalDetailResponse
     */
    @RequestMapping(value = "/count-by-terminal-detail-its")
    @Login
    @Permissions("51013")
    public Response countByTerminalDetailForStore(HttpSession session,
                                                  @Validated @RequestBody CountByTerminalDetailRequest param) {
        MemberVolumeDetailCondition condition = countByTerminalInfoConvert(param);
        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());

        PagingResult<MemberVolumeDetailDTO> storeList = memberCountQuery.getMemberVolumeDetailForStore(condition);
        List<CountByTerminalDetailResponse> countByTerminalDetailRespons =
                CJBeanUtils.convertCollection(storeList.getItems(), CountByTerminalDetailResponse.class, (source, target) -> {
                    if (source.getStoreUser().equals("-")) {
                        target.setStoreUser(userCommon.getMerchantName());
                    }
                });
        return ResponseUtils.successPage(param.getPage(), storeList,
                "dataList", countByTerminalDetailRespons);
    }

    /**
     * 按照终端类型统计注册会员量明细--门店权限 导出
     */
    @RequestMapping(value = "/export/count-by-terminal-detail-its")
    @Login
    public void exportCountByTerminalDetailForStore(HttpSession session,
                                                    HttpServletResponse response,
                                                    HttpServletRequest request) throws ParseException, IOException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        String terminalType = request.getParameter("registerTerminalType");
        String nameOrMobile = request.getParameter("nameOrMobile");
        String pageNo = request.getParameter("pageNO");
        CountByTerminalDetailRequest param = new CountByTerminalDetailRequest();
        if (!"".equals(startTime)) {
            param.setStartTime(sdf.parse(startTime));
        }
        if (!"".equals(endTime)) {
            param.setEndTime(sdf.parse(endTime));
        }
        if (!"".equals(terminalType)) {
            param.setTerminalType(Byte.valueOf(terminalType));
        }
        if (!"".equals(nameOrMobile)) {
            param.setNameOrMobile(nameOrMobile);
        }

        Page page = new Page();
        if (!"".equals(pageNo)) {
            page.setPageNO(Integer.parseInt(pageNo));
        }
        page.setEveryPageCount(EXPORT_SIZE);
        param.setPage(page);


        OutputStream out = response.getOutputStream();
        RequestHeadersUtil.exportRequestHeader(response, "按照终端类型统计注册会员量明细");

        OutputStreamWriter osw = null;
        BufferedWriter bw = null;

        try {
            List<CountByTerminalDetailResponse> list = getExportCountByTerminalDetailForStore(session, param);

            osw = new OutputStreamWriter(out, "GBK");
            bw = new BufferedWriter(osw);
            getExportCountByTerminalDetail(sdf, bw, list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bw != null) {
                bw.close();
                bw = null;
            }
            if (osw != null) {
                osw.close();
                osw = null;
            }
            if (out != null) {
                out.close();
                out = null;
            }
        }


    }

    private void getExportCountByTerminalDetail(SimpleDateFormat sdf, BufferedWriter bw, List<CountByTerminalDetailResponse> list) throws IOException {

        bw.append("序号").append(",")
                .append("注册时间").append(",")
                .append("会员卡号").append(",")
                .append("会员名称").append(",")
                .append("手机号").append(",")
                .append("操作人").append(",")
                .append("\r");

        if (list != null && !list.isEmpty()) {
            for (int i = 0; i < list.size(); i++) {
                CountByTerminalDetailResponse data = list.get(i);
                String registerTime = null;
                if (data.getRegisterTime() != null) {
                    registerTime = sdf.format(data.getRegisterTime());
                }
                bw.append(String.valueOf(i + 1)).append(",")
                        .append(registerTime == null ? "" : registerTime).append(",")
                        .append(data.getMemberCardNum() == null ? "" : data.getMemberCardNum()).append(",")
                        .append(data.getName() == null ? "" : data.getName()).append(",")
                        .append(data.getMobile() == null ? "" : data.getMobile()).append(",")
                        .append(data.getStoreUser() == null ? "" : data.getStoreUser()).append(",")
                        .append("\r");
            }
        }
    }

    private List<CountByTerminalDetailResponse> getExportCountByTerminalDetailForStore(HttpSession session, @Validated @RequestBody CountByTerminalDetailRequest param) {
        MemberVolumeDetailCondition condition = countByTerminalInfoConvert(param);
        ThreadLocalUser userCommon = (ThreadLocalUser) ThreadContext.get(Constants.CURRENT_LOGIN_USER_KEY);
        condition.setMerchantId(userCommon.getMerchantId());
        condition.setRegisterStoreId(userCommon.getStoreId());

        PagingResult<MemberVolumeDetailDTO> storeList = memberCountQuery.getMemberVolumeDetailForStore(condition);
        return CJBeanUtils.convertCollection(storeList.getItems(), CountByTerminalDetailResponse.class);
    }

    private MemberVolumeDetailCondition countByTerminalInfoConvert(CountByTerminalDetailRequest param) {
        MemberVolumeDetailCondition condition = new MemberVolumeDetailCondition();
        condition.setStartTime(param.getStartTime());
        condition.setEndTime(param.getEndTime());
        condition.setNameOrMobile(param.getNameOrMobile());
        condition.setSex(param.getSex());
        condition.setTerminalType(param.getTerminalType());
        condition.setStoreName(param.getStoreName());
        PageUtils.copyPage(condition, param.getPage());
        return condition;
    }
}
